#include "viml/builtin_dict.h"
#include "viml/builtin_list.h"
#include "viml/value.h"
#include "viml/vm.h"
#include <gtest/gtest.h>

using namespace viml;

TEST(DictBuiltinTest, Keys) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["a"] = Value::make_number(1);
    entries["b"] = Value::make_number(2);
    entries["c"] = Value::make_number(3);
    
    // 调用keys函数
    std::vector<Value> args = {dict};
    Value result = keys_builtin(args);
    
    // 验证结果
    ASSERT_TRUE(result.is_list());
    auto& list = result.as_list();
    ASSERT_EQ(list.size(), 3);
    
    // 检查键是否存在（顺序可能不固定）
    bool found_a = false, found_b = false, found_c = false;
    for (const auto& key : list) {
        ASSERT_TRUE(key.is_string());
        if (key.as_string() == "a") found_a = true;
        if (key.as_string() == "b") found_b = true;
        if (key.as_string() == "c") found_c = true;
    }
    ASSERT_TRUE(found_a && found_b && found_c);
}

TEST(DictBuiltinTest, Values) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["a"] = Value::make_number(1);
    entries["b"] = Value::make_number(2);
    entries["c"] = Value::make_number(3);
    
    // 调用values函数
    std::vector<Value> args = {dict};
    Value result = values_builtin(args);
    
    // 验证结果
    ASSERT_TRUE(result.is_list());
    auto& list = result.as_list();
    ASSERT_EQ(list.size(), 3);
    
    // 检查值是否存在（顺序可能不固定）
    bool found_1 = false, found_2 = false, found_3 = false;
    for (const auto& value : list) {
        ASSERT_TRUE(value.is_number());
        if (value.as_number() == 1) found_1 = true;
        if (value.as_number() == 2) found_2 = true;
        if (value.as_number() == 3) found_3 = true;
    }
    ASSERT_TRUE(found_1 && found_2 && found_3);
}

TEST(DictBuiltinTest, Items) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["a"] = Value::make_number(1);
    entries["b"] = Value::make_number(2);
    
    // 调用items函数
    std::vector<Value> args = {dict};
    Value result = items_builtin(args);
    
    // 验证结果
    ASSERT_TRUE(result.is_list());
    auto& list = result.as_list();
    ASSERT_EQ(list.size(), 2);
    
    // 检查键值对
    bool found_a = false, found_b = false;
    for (const auto& item : list) {
        ASSERT_TRUE(item.is_list());
        auto& kv_pair = item.as_list();
        ASSERT_EQ(kv_pair.size(), 2);
        ASSERT_TRUE(kv_pair[0].is_string());
        
        if (kv_pair[0].as_string() == "a") {
            ASSERT_EQ(kv_pair[1].as_number(), 1);
            found_a = true;
        } else if (kv_pair[0].as_string() == "b") {
            ASSERT_EQ(kv_pair[1].as_number(), 2);
            found_b = true;
        }
    }
    ASSERT_TRUE(found_a && found_b);
}

TEST(DictBuiltinTest, HasKey) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["key1"] = Value::make_number(100);
    
    // 测试存在的键
    std::vector<Value> args1 = {dict, Value::string("key1")};
    Value result1 = has_key_builtin(args1);
    ASSERT_TRUE(result1.is_boolean());
    ASSERT_TRUE(result1.as_boolean());
    
    // 测试不存在的键
    std::vector<Value> args2 = {dict, Value::string("key2")};
    Value result2 = has_key_builtin(args2);
    ASSERT_TRUE(result2.is_boolean());
    ASSERT_FALSE(result2.as_boolean());
}

TEST(DictBuiltinTest, Len) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["a"] = Value::make_number(1);
    entries["b"] = Value::make_number(2);
    
    // 调用len函数
    std::vector<Value> args = {dict};
    Value result = len_dict_builtin(args);
    
    // 验证结果
    ASSERT_TRUE(result.is_number());
    ASSERT_EQ(result.as_number(), 2);
}

TEST(DictBuiltinTest, Get) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["key1"] = Value::make_number(42);
    
    // 测试获取存在的键
    std::vector<Value> args1 = {dict, Value::string("key1")};
    Value result1 = get_builtin(args1);
    ASSERT_TRUE(result1.is_number());
    ASSERT_EQ(result1.as_number(), 42);
    
    // 测试获取不存在的键，无默认值
    std::vector<Value> args2 = {dict, Value::string("key2")};
    Value result2 = get_builtin(args2);
    ASSERT_TRUE(result2.is_nil());
    
    // 测试获取不存在的键，有默认值
    std::vector<Value> args3 = {dict, Value::string("key2"), Value::make_number(100)};
    Value result3 = get_builtin(args3);
    ASSERT_TRUE(result3.is_number());
    ASSERT_EQ(result3.as_number(), 100);
}

TEST(DictBuiltinTest, Remove) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["key1"] = Value::make_number(42);
    entries["key2"] = Value::make_number(100);
    
    // 删除存在的键
    std::vector<Value> args1 = {dict, Value::string("key1")};
    Value result1 = remove_builtin(args1);
    ASSERT_TRUE(result1.is_number());
    ASSERT_EQ(result1.as_number(), 42);
    
    // 验证键已被删除
    ASSERT_EQ(entries.size(), 1);
    ASSERT_TRUE(entries.find("key1") == entries.end());
    ASSERT_TRUE(entries.find("key2") != entries.end());
}

TEST(DictBuiltinTest, Copy) {
    // 创建测试字典
    Value dict = Value::dict();
    auto& entries = dict.as_dict();
    entries["a"] = Value::make_number(1);
    entries["b"] = Value::make_number(2);
    
    // 调用copy函数（使用修改后的copy_builtin）
    std::vector<Value> args = {dict};
    Value result = copy_builtin(args);
    
    // 验证结果
    ASSERT_TRUE(result.is_dict());
    auto& copied_entries = result.as_dict();
    ASSERT_EQ(copied_entries.size(), 2);
    ASSERT_EQ(copied_entries.at("a").as_number(), 1);
    ASSERT_EQ(copied_entries.at("b").as_number(), 2);
    
    // 验证是浅拷贝
    ASSERT_TRUE(&entries != &copied_entries);  // 不同的对象
    ASSERT_EQ(entries.at("a").raw_bits(), copied_entries.at("a").raw_bits());  // 相同的值
}